package cn.itsource.ldj.user.service.impl;

import cn.itsource.ldj.base.domain.CodeTypeContants;
import cn.itsource.ldj.base.service.impl.BaseServiceImpl;
import cn.itsource.ldj.user.domain.LoginInfo;
import cn.itsource.ldj.user.domain.User;
import cn.itsource.ldj.user.domain.WxInfoContants;
import cn.itsource.ldj.user.domain.WxUser;
import cn.itsource.ldj.user.mapper.LoginInfoMapper;
import cn.itsource.ldj.user.mapper.UserMapper;
import cn.itsource.ldj.user.mapper.WxUserMapper;
import cn.itsource.ldj.user.service.IWxUserService;
import cn.itsource.ldj.util.AjaxResult;
import cn.itsource.ldj.util.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.FastjsonSockJsMessageCodec;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class WxUserServiceImpl extends BaseServiceImpl<WxUser> implements IWxUserService {

    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LoginInfoMapper loginInfoMapper;

    /* 微信登录 */
    @Override
    public AjaxResult login(Map<String, Object> map) {
        // 获取code
        String code = map.get("code").toString();
        System.out.println("code:" + code);

        String url = WxInfoContants.GET_ACCESS_TOKEN
                .replace("APPID",WxInfoContants.APPID)
                .replace("SECRET",WxInfoContants.SECRET)
                .replace("CODE",code);

        // 发送请求，获取access_token
        String wxresult = HttpUtil.sendGet(url);
        // 将微信平台返回的json字符串转换为json格式对象
        JSONObject jb = JSON.parseObject(wxresult);
        // 获取openid和access_token
        String openid = jb.getString("openid");
        String access_token = jb.getString("access_token");

        // 根据openid查询数据库中是否有这个用户，检查是否是第一次登录
        WxUser wxUser = wxUserMapper.findByOpenid(openid);
        if (wxUser != null && wxUser.getUser_id() != null) {
            // 直接登录
            LoginInfo loginInfo = loginInfoMapper.findByUid(wxUser.getUser_id());
            return noPwdLogin(loginInfo);
        } else {
            System.out.println("绑定");
            // 跳转到绑定页面
            return new AjaxResult("bindwechart.html?openid="+ openid +"&access_token=" + access_token);
        }
    }

    /* 绑定微信验证码 */
    @Override
    @Transactional
    public AjaxResult bind(Map<String, String> map) {

        // 取出绑定页面填写的数据
        String phone = map.get("phone");
        String code = map.get("code");
        String openId = map.get("openId");
        String access_token = map.get("access_token");

        // 验证验证码是否正确
        // 取出redis中保存的验证码
        String codeAndTime = (String)redisTemplate.opsForValue().get(CodeTypeContants.BIND_CODE + ":" + phone);
        String redisCode = codeAndTime.split(":")[0];
        if (!code.equals(redisCode)) {
            throw new RuntimeException("验证码错误，请重新输入");
        }

        // 判断是否注册绑定过这个手机号码
        User user = userMapper.findByPhone(phone);
        if (user == null) {
            // 生成一个用户
            User newUser = new User();
            // 设置已有的值和初始化状态
            newUser.setPhone(phone);
            newUser.setState(1);
            newUser.setUsername("u_" + phone);

            // 添加到数据库
            userMapper.save(newUser);

            // 将user对象添加到登录信息表中
            LoginInfo loginInfo = userToLoginInfo(newUser);
            // 将logininfo对象存放在数据库中
            loginInfoMapper.save(loginInfo);
        }


        // 根据微信平台获取微信用户信息
        String url = WxInfoContants.GET_USERINFO
                .replace("OPENID",openId)
                .replace("ACCESS_TOKEN",access_token);

        // 发送请求，获取用户个人信息
        String wxInfoResult = HttpUtil.sendGet(url);
        // 将微信平台返回的json字符串转换为json格式对象
        JSONObject jb = JSON.parseObject(wxInfoResult);
        // 创建微信用户对象，并设置值
        WxUser wxUser = new WxUser();
        wxUser.setOpenid(jb.getString("openid"));
        wxUser.setNickname(jb.getString("nickname"));
        wxUser.setHeadimgurl(jb.getString("headimgurl"));
        wxUser.setSex(jb.getInteger("sex"));
        wxUser.setUnionid(jb.getString("unionid"));
        wxUser.setAddress(jb.getString("country") + jb.getString("province") + jb.getString("city"));
        // 获取绑定手机用户的id
        Long user_id = userMapper.findByPhone(phone).getId();
        wxUser.setUser_id(user_id);

        // 保存到数据库
        wxUserMapper.save(wxUser);

        LoginInfo loginInfo = loginInfoMapper.findByUid(user_id);
        // 免密登录
        return noPwdLogin(loginInfo);
    }


    /* 将user对象数据移植到logininfo中 */
    private LoginInfo userToLoginInfo(User user) {

        LoginInfo loginInfo = new LoginInfo();
        // 设置是根据哪个表来登录
        loginInfo.setType(1);
        // 将user对象中的数据copy到logininfo对象中
        BeanUtils.copyProperties(user, loginInfo);
        // 将user对象的id设置到logininfo的uid中
        loginInfo.setUid(user.getId());
        return loginInfo;
    }

    /* 用户免密登录 */
    public AjaxResult noPwdLogin(LoginInfo loginInfo) {

            /* 将登录用户保存到redis中 */
            String token = UUID.randomUUID().toString();
            redisTemplate.opsForValue().set(token, loginInfo, 30, TimeUnit.MINUTES);

            Map<String, Object> map = new HashMap();
            // 清空敏感数据
            loginInfo.setPassword("");
            loginInfo.setSalt("");

            // map中存入token和登录用户返回给前端
            map.put("token", token);
            map.put("loginInfo", loginInfo);

            // 将map返回给前端
            return AjaxResult.me().setResultObj(map);
        }
}
